<!DOCTYPE html>
<html>
<body>
  <div id="root"></div>
  <div id="root1"></div>
  <div id="root2"></div>
</body>
<script src="./reactv18/babel.min.js"></script>
<script src="./reactv18/react.development.js"></script>
<script src="./reactv18/react-dom.development.js"></script>
<!-- 1. 引入类型限制js, 在react15版本以前，这个集成在react库当中，之后独立开来 -->
<script src="./reactv18/prop-types.js"></script>

<script type="text/babel">
  class Son extends React.Component{

    render(){
      console.log("son- render")
      return(
        <div>我是子组件son, 我的值是：{this.props.count}</div>
      )
    }
  }


  
  class Count extends React.Component{
    constructor(props){
      console.log("count-constructor")
      super(props)
      this.state =  {count: 0}
    }

    // 新钩子函数，必须加Static，必须返回状态对象或null, 只要设置了这个方法，状态要看该方法脸色
    // 若state的值在任何时候都取决于Props，那么可以使用
    static getDerivedStateFromProps(props, state){
      console.log("getDerivedStateFromProps", props, state)
      // return props // 一旦把状态对象返回，状态就没法修改了
      return null
    }

    // 这个钩子必须返回一个快照对象，或者null，无返回值，会提示警告
    // 如果你实现了 getSnapshotBeforeUpdate，React 会在 React 更新 DOM 之前时直接调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息（例如滚动的位置）。此生命周期方法返回的任何值都将作为参数传递给 componentDidUpdate。
    // 在更新之前 拍个照
    getSnapshotBeforeUpdate(){
      console.log('getSnapshotBeforeUpdate')
      // return null 
      return "huangchao"
    }

    componentDidMount(){
      console.log("componentDidMount")
    }
    // 组件将要卸载的狗子
    componentWillUnmount(){
      console.log("componentWillUnmount")
    }

    // 控制组件更新的阀门
    shouldComponentUpdate(){
      console.log("shouldComponentUpdate")
      return true  // true，继续执行， false，组件更新中断 
    }


    // 更新之后 a先前的props, b之前的状态
    componentDidUpdate(preProps, preState, snapShotValue){
      console.log("componentDidUpdate", preProps, preState, snapShotValue)
    }

    add=()=>{
      this.setState({count: ++this.state.count})
    }

    rm =()=>{
      // 卸载DOM reactjs 18中 不支持使用此方法， 改用root.unmount()方法即可
      // ReactDOM.unmountComponentAtNode(document.getElementById("root"))
      root.unmount();
    }

    force=()=>{
      this.forceUpdate()  // 强制更新，会绕过shouldComponentUpdate，走后续的狗子
    }

    render(){
      const {count} = this.state
      console.log("render")
      return (
        <div>
          <h2>当前求和为{count}</h2>
          <button onClick={this.add}>点我+1</button>
          <button onClick={this.rm}>卸载组件</button>
          <button onClick={this.force}>不更改任何状态中的数据，强制更新一下</button>

          <Son count={this.state.count}/>
        </div>
      )
    }
  }
  const container = document.getElementById('root')
  const root = ReactDOM.createRoot(container)
  root.render(<Count count="199"/>)
</script>
</html>
